home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / x11 / lib / magnify.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-25  |  7.6 KB  |  279 lines

  1. /*
  2. %    magnify . c
  3. %
  4. */
  5. #include "tuner.h"
  6.  
  7. void
  8. mag_pan(img, action, bx, by, new_mag_fact, stingy)
  9. image_information    *img;
  10. int    action, bx, by, new_mag_fact;
  11. {
  12. Boolean    fast_pan = False, redraw = False, redither = False;
  13. int    omag_x, omag_y, mag_f = abs(img->mag_fact), ix, iy;
  14.  
  15. #ifndef    SCROLLBAR_on_CANVAS
  16.     bx += img->x;    by += img->y;
  17. #endif
  18.     ix = img->mag_x + bx / mag_f,
  19.     iy = img->mag_y + by / mag_f;
  20.  
  21.  
  22.     /* we could re-open the img->name to handle this ... */
  23.     if (img->scan_data == NULL)
  24.         return;
  25.  
  26.     switch (action) {
  27.     /*
  28.      * Normalize has to switch the current mag factor with 1 if they
  29.      * differ... It also remembers the old mag_x and mag_y and stuff.  It
  30.      * should use the pixmaps to refresh, so that it will be fast when
  31.      * toggeling in this mode...
  32.      */
  33.     case ACTION_SWITCH_MAG_MODE:
  34.     if (img->mag_fact == img->save_mag_fact)
  35.         return;
  36.     else {
  37.         if (img->mag_fact == 1) {
  38.         img->mag_mode = True;
  39.         img->mag_fact = img->save_mag_fact;
  40.         img->mag_x = img->save_mag_x;
  41.         img->mag_y = img->save_mag_y;
  42.         img->mag_w = img->save_mag_w;
  43.         img->mag_h = img->save_mag_h;
  44.         img->save_mag_x = img->save_mag_y = 0;
  45.         img->save_mag_w = img->w; img->save_mag_h = img->h;
  46.         img->save_mag_fact = 1;
  47.         img->refresh_pixmap = img->mag_pixmap;
  48.         } else {
  49.         img->mag_mode = False;
  50.         img->save_mag_x = img->mag_x;
  51.         img->save_mag_y = img->mag_y;
  52.         img->save_mag_w = img->mag_w;
  53.         img->save_mag_h = img->mag_h;
  54.         img->save_mag_fact = img->mag_fact;
  55.         img->mag_x = img->mag_y = 0;
  56.         img->mag_w = img->w; img->mag_h = img->h;
  57.         img->mag_fact = 1;
  58.         img->refresh_pixmap = img->pixmap;
  59.         }
  60.         redraw = True;
  61.     }
  62.     break;
  63.     case ACTION_MAGNIFY:
  64.     case ACTION_UNMAGNIFY:
  65.     if (!new_mag_fact)    new_mag_fact = -2;
  66.     if ((img->mag_fact=new_mag_fact) < 2)    {
  67.         img->mag_x = img->mag_y = 0;
  68.         img->mag_w = img->w; img->mag_h = img->h;
  69.     }
  70.     if ((mag_f=abs(new_mag_fact)) < 2)    {
  71.         img->mag_fact = 1;
  72.         img->refresh_pixmap = img->pixmap;
  73.         if (img->mag_mode)
  74.             redraw = True;
  75.         img->mag_mode = False;
  76.         break;
  77.     } else img->mag_mode = True;
  78.     if (new_mag_fact < 0)
  79.         mag_f = 1;
  80.  
  81.     img->mag_x = ix - (img->resize_w >> 1)/mag_f;
  82.     img->mag_y = iy - (img->resize_h >> 1)/mag_f;
  83.  
  84.     img->mag_w = img->w/mag_f;
  85.     img->mag_h = img->h/mag_f;
  86.  
  87.     if (!img->mag_pixmap && !img->pixmap_failed && !stingy) {
  88.         img->mag_pixmap = XCreatePixmap(img->dpy, img->window,
  89.                     img->w, img->h, img->dpy_depth);
  90.         check_pixmap_allocation(img);
  91.     }
  92.  
  93.     img->refresh_pixmap = img->mag_pixmap;
  94.  
  95.     redither = redraw = True;
  96.     break;
  97.  
  98.     case ACTION_PAN:
  99.     fast_pan = img->mag_mode;  /* are we REALLY just panning around? */
  100.     omag_x = img->mag_x;
  101.     omag_y = img->mag_y;
  102.  
  103.     if (!img->mag_mode) {
  104.         img->mag_fact = img->save_mag_fact;
  105.         img->save_mag_fact = 1;
  106.     }
  107.     if (img->mag_fact > 1)
  108.         img->mag_mode = True;
  109.     else    return;
  110.  
  111.     img->refresh_pixmap = img->mag_pixmap;
  112.  
  113.     img->mag_x = ix - (img->resize_w >> 1)/mag_f;
  114.     img->mag_y = iy - (img->resize_h >> 1)/mag_f;
  115.  
  116.     /* Isnt this always like this? */
  117.     img->mag_w = img->w/mag_f;
  118.     img->mag_h = img->h/mag_f;
  119.  
  120.     redither = redraw = True;
  121.     break;
  122.     }
  123.  
  124.     /* check bounds */
  125.     if (img->mag_x < 0)
  126.     img->mag_x = 0;
  127.     if (img->mag_y < 0)
  128.     img->mag_y = 0;
  129.     
  130.     if (img->mag_x + img->mag_w > img->w)
  131.     img->mag_x = img->w - img->mag_w - (img->mag_w * mag_f < img->w);
  132.     if (img->mag_y + img->mag_h > img->h)
  133.     img->mag_y = img->h - img->mag_h - (img->mag_h * mag_f < img->h);
  134.  
  135.     /* check bounds */
  136.     if (img->mag_x < 0)
  137.     img->mag_x = 0;
  138.     if (img->mag_y < 0)
  139.     img->mag_y = 0;
  140.  
  141.     /* let the suckers know that we are thinking */
  142.     set_watch_cursor(img->window);
  143.  
  144.     /*
  145.      * Some could argue that this fast_pan shit is a waste of time, but it
  146.      * does speed things up a bunch, and its really hard to understand.
  147.      * Sorry, no fancy pictures in the comments.  Just code.  We figure out
  148.      * which rectangle is blt-able.  We blt it on the server side, and on the
  149.      * client side (my fancy XCopyImage) and then MAG_scanline the exposed
  150.      * area and XPutImage that stuff too...  Dont change it cuz its right.
  151.      */
  152.     if (fast_pan) {
  153.     int    width, hight,
  154.         src_x, src_y, dst_x, dst_y,
  155.         pwidth = omag_x - img->mag_x,
  156.         phight = omag_y - img->mag_y;
  157.  
  158.     pwidth = img->mag_w - ((pwidth < 0) ? - pwidth : pwidth);
  159.     phight = img->mag_h - ((phight < 0) ? - phight : phight);
  160.  
  161.     /*
  162.      * pwidth and phight now contain the size of the non-changing
  163.      * (BLT-able) portion of the viewport in rle_pixel space.
  164.      */
  165.     width = pwidth * img->mag_fact + (img->w - img->mag_w * img->mag_fact);
  166.     hight = phight * img->mag_fact + (img->h - img->mag_h * img->mag_fact);
  167.  
  168.     /* Now we compute the src_xy and dst_xy for the pixel copy */
  169.     if (omag_x < img->mag_x)
  170.         dst_x = 0,    src_x = img->w - width;
  171.     else
  172.         src_x = 0,    dst_x = img->w - width;
  173.  
  174.     if (omag_y < img->mag_y)
  175.         dst_y = 0,    src_y = img->h - hight;
  176.     else
  177.         src_y = 0,    dst_y = img->h - hight;
  178.  
  179.     /* subtract partial pixels if we are going right */
  180.     if (omag_x < img->mag_x)
  181.         width -= img->w - img->mag_w * img->mag_fact;
  182.  
  183.     /* subtract partial pixels if we are going down */
  184.     if (omag_y < img->mag_y)
  185.         hight -= img->h - img->mag_h * img->mag_fact;
  186.  
  187.     if (src_x == dst_x && src_y == dst_y)
  188.         redraw = redither = False;
  189.     else {
  190.         /* XCopyImage is only implemented for 8 and 32 bit image pixels */
  191.         if (img->refresh_pixmap && XCopyImage(img->image, src_x, src_y,
  192.                         width, hight, dst_x, dst_y))
  193.         {
  194.         XCopyArea(img->dpy, img->refresh_pixmap, img->refresh_pixmap,
  195.             img->gc, src_x, src_y, width, hight, dst_x, dst_y);
  196.  
  197.         if (dst_y) {
  198.            (*img->MAG_scanline)(img, img->mag_x, img->mag_y,
  199.                     img->mag_fact, 0, 0,
  200.                     img->w, dst_y, img->image);
  201.  
  202.             XPutImage(img->dpy, img->refresh_pixmap, img->gc, img->image,
  203.                 0, 0, 0, 0, img->w, dst_y);
  204.         }
  205.         else {
  206.             if (hight < img->h) {
  207.             (*img->MAG_scanline)
  208.                 (img, img->mag_x, img->mag_y + phight,
  209.                 img->mag_fact, 0, hight,
  210.                 img->w, img->h - hight, img->image);
  211.             XPutImage(img->dpy, img->refresh_pixmap, img->gc,
  212.                 img->image, 0, hight, 0, hight,
  213.                 img->w, img->h - hight);
  214.             }
  215.         }
  216.  
  217.         if (dst_x) {
  218.             if (hight && width < img->w) {
  219.             (*img->MAG_scanline)
  220.                 (img, img->mag_x, img->mag_y +
  221.                 ((dst_y) ? img->mag_h - phight : 0), img->mag_fact,
  222.                 0, dst_y, img->w - width, hight, img->image);
  223.  
  224.             XPutImage(img->dpy, img->refresh_pixmap, img->gc,img->image,
  225.                 0, dst_y, 0, dst_y, img->w - width, hight);
  226.             }
  227.         }
  228.         else {
  229.             if (hight && width < img->w) {
  230.             (*img->MAG_scanline)
  231.                 (img, img->mag_x + pwidth, img->mag_y +
  232.                 ((dst_y) ? img->mag_h - phight: 0), img->mag_fact,
  233.                 width, dst_y, img->w - width, hight, img->image);
  234.  
  235.             XPutImage(img->dpy, img->refresh_pixmap, img->gc,
  236.                   img->image, width, dst_y, width, dst_y,
  237.                   img->w - width, hight);
  238.             }
  239.         }
  240.  
  241.         /*
  242.         * We already redithered...  If XCopyImage failed we arent
  243.         * here and we have to redither the whole thing below.
  244.         */
  245.         redither = False;
  246.         }
  247.     }
  248.     }
  249.  
  250.     /* redither the whole thing, but repaint part */
  251.     mag_f = abs(img->mag_fact);
  252.     bx = img->w,    by = img->h;
  253.     if (img->mag_fact < (ix=iy=0))
  254.         bx /= mag_f,    by /= mag_f;
  255.     mag_f = !img->refresh_pixmap;
  256.     if (redither || (redraw && mag_f))    {
  257.     (*img->MAG_scanline)(img, img->mag_x, img->mag_y,
  258.             img->mag_fact, 0, 0, img->w, img->h, img->image);
  259.     if (mag_f)
  260.         ix = img->x,    iy = img->y;
  261.     XPutImage(img->dpy, mag_f ? img->window:img->refresh_pixmap,
  262.           img->gc, img->image, ix, iy, 0, 0, bx, by);
  263.     }
  264.  
  265.     if (redraw && !mag_f)    {
  266.     ix = iy = 0;
  267. #ifdef SCROLLBAR_on_CANVAS
  268.     ix = img->x;    iy = img->y;
  269. #endif
  270.     if (bx > img->resize_w)    bx = img->resize_w;
  271.     if (by > img->resize_h)    by = img->resize_h;
  272.     XCopyArea(img->dpy, img->refresh_pixmap, img->window, img->gc,
  273.         img->x, img->y, bx, by, ix, iy);
  274.     }
  275. set_left_ptr_cursor(img->window);
  276. Draw_ImageScrollBars(img);
  277. if (img->sub_img)    DrawCrop(img, 0, redraw | redither);
  278. }
  279.